const Koa = require('koa');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const logger = require('koa-logger');
const fastXmlParser = require('fast-xml-parser');
const xmlbody = require('koa-xml-body');
const koaStatic = require('koa-static');
const config = JSON.parse(fs.readFileSync(path.join(__dirname, "config.json")));

main()

//启动入口
function main() {
    let app = new Koa();
    app.use(logger());
    app.use(xmlbody());

    //静态资源文件
    app.use(koaStatic(path.join(__dirname, '/static')));

    app.use(async (ctx, next) => {
        if (ctx.request.method === 'GET') {
            //检查是否微信服务器
            if (checkWechatServer(ctx)) {
                var nonce = ctx.request.query.nonce;
                ctx.body = echostr;
            }
        }
        await next();
    });

    //处理微信传过来的xml数据，转化为json存于request.body
    app.use(async (ctx, next) => {
        if (ctx.request.method === 'POST') {
            //引用插件后不需要解析
            // var postdata = "";
            // ctx.req.addListener('data', (data) => {
            //     postdata += data
            // })
            // ctx.req.addListener("end", function () {
            //     console.log(fastXmlParser.parse(postdata).xml)
            //     ctx.request.body = fastXmlParser.parse(postdata).xml;
            // })

            ctx.request.body = ctx.request.body.xml;
        }
        await next();
    });


    //处理消息
    let handlers = resolveHandlers();
    app.use(async (ctx, next) => {
        await next();
        if (ctx.request.method === 'POST') {
            // if (checkWechatServer(ctx)) {
            for (let index in handlers) {
                let handler = handlers[index];
                handler.handle(ctx.request.body, ctx);
            }
            if (ctx.body === undefined) {
                ctx.body = '';
            }
            // }
        }
    });

    app.listen(config.port);
    console.log('server\'s status is running.');
}

//获取消息处理器
function resolveHandlers() {
    let handlers = [];
    let handlersDir = path.join(__dirname, 'handlers');
    let filenames = fs.readdirSync(handlersDir)
    for (let index in filenames) {
        let filename = filenames[index];
        if (filename.endsWith('.js')) {
            let handler = require(path.join(handlersDir, filename));
            if (handler.enable === true || handler.enable === undefined) {
                handlers.push(handler);
            }
        }
    }
    return handlers;
}

function checkWechatServer(ctx) {
    var signature = ctx.request.query.signature;

    var echostr = ctx.request.query.echostr;

    var token = config.token;
    var timestamp = ctx.request.query.timestamp;
    var nonce = ctx.request.query.nonce;

    var tmpArr = [token, timestamp, nonce];
    tmpArr.sort();

    var tmpStr = tmpArr[0] + tmpArr[1] + tmpArr[2];

    var sha1 = crypto.createHash('sha1');

    sha1.update(tmpStr)
    var signatrue1 = sha1.digest('hex');

    // if (signatrue1 === signature) {
    //     console.log('check wechat server success');
    // }
    return signature == signatrue1;
}



